/**
 * 
 */
package controller.xml;

import java.io.File;

import model.preprocessor.PreProcessorFactory;
import model.session.CNFUse;
import model.session.PreprocessorExecutionBlock;
import model.session.SessionBlock;
import model.solver.SolverFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * Use to parse a preprocessor cnfuse (just means a preprocessor and its cnfuse result) a in the
 * exported session in XML.
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class PreProcCNFUseXMLHandler extends XMLHandler {
	private PreprocessorExecutionBlock	block	= null;
	private CNFUse						cnfuse	= null;
	private PreProcCNFUseXMLStatus		status	= PreProcCNFUseXMLStatus.NONE;
	private PreProcessorFactory			prefactory;
	private SolverFactory				solfactory;
	private SessionBlock				first	= null;
	private File						directory;

	/**
	 * Create {@link PreProcCNFUseXMLHandler} to parse a preprocessor execution : preproc and cnfuse
	 * result.
	 * 
	 * @param first
	 *            first block of the session
	 * @param prefactory
	 *            {@link PreProcessorFactory}
	 * @param solfactory
	 *            {@link SolverFactory}
	 * @param directory
	 *            directory of the import
	 */
	public PreProcCNFUseXMLHandler(SessionBlock first, PreProcessorFactory prefactory, SolverFactory solfactory, File directory) {
		this.solfactory = solfactory;
		this.prefactory = prefactory;
		this.first = first;
		this.directory = directory;
	}


	@Override
	public boolean characters2(char[] ch, int start, int length) throws SAXException {
		throw new SAXException("not supposed to receive character in this status");
	}

	@Override
	public boolean endDocument2() throws SAXException {
		return false;
	}

	@Override
	public boolean endElement2(String uri, String localName, String qName) throws SAXException {
		switch (status) {
		case NONE:
			return false;

		case PREPROC_EXECUTION:
			if (qName.equals(XMLBaliseFormat.PREPROC_EXECUTION))
			{// ferme preproc execution
				status = PreProcCNFUseXMLStatus.NONE;
				block = ((PreProcessorExecutionXMLHandler) delegate).getPreprocBlock();
				if (block == null)
					throw new SAXException("problem with PREPROC BLOCK");
				delegate = null;
				return true;
			}
			throw new SAXException("end of PREPROC EXECUTION was expected");

		case CNFUSE:
			if (qName.equals(XMLBaliseFormat.CNFUSE))
			{// ferme cnfuse
				status = PreProcCNFUseXMLStatus.NONE;
				cnfuse = ((CNFUseXMLHandler) delegate).getCnfuse();
				if (cnfuse == null)
					throw new SAXException("problem with CNFUSE");
				delegate = null;
				return true;
			}
			throw new SAXException("end of CNFUSE was expected");
		}

		// attend une fin de balise qui existe pas...
		throw new SAXException("an other end of element was expected");
	}

	@Override
	public boolean startElement2(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
		if (status != PreProcCNFUseXMLStatus.NONE)
			throw new SAXException("already have a started element");

		if (arg2.equals(XMLBaliseFormat.PREPROC_EXECUTION))
		{// balise preproc execution
			if (block != null)
				throw new SAXException("already have a PREPROC EXECUTION");

			// set les donne pour recupere le preproc
			status = PreProcCNFUseXMLStatus.PREPROC_EXECUTION;
			delegate = new PreProcessorExecutionXMLHandler(first, prefactory);

			return true;
		}

		// si pas de preproc refuse les autres
		if (block == null)
			throw new SAXException("need a PREPROC EXECUTION first");

		if (arg2.equals(XMLBaliseFormat.CNFUSE))
		{// balise cnfuse
			if (cnfuse != null)
				throw new SAXException("already have a CNFUSE");

			// set les donne pour recupere la CNFUSE
			status = PreProcCNFUseXMLStatus.CNFUSE;
			delegate = new CNFUseXMLHandler(first, prefactory, solfactory, directory);

			return true;
		}

		// peut pas commencer balise qui existe pas
		throw new SAXException("unexpected balise: " + arg2);
	}


	/**
	 * Return the {@link PreprocessorExecutionBlock}.
	 * 
	 * @return the block
	 */
	public PreprocessorExecutionBlock getBlock() {
		return block;
	}


	/**
	 * Return the {@link CNFUse}.
	 * 
	 * @return the cnfuse
	 */
	public CNFUse getCnfuse() {
		return cnfuse;
	}


}
